package com.example.sams.interceptor;

import com.example.sams.utils.JwtUtil;
import com.example.sams.utils.LoginUser;
import com.example.sams.utils.ResultUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@Component // 注册为Spring Bean，供后续配置使用
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil; // 注入已有的JWT工具类

    /**
     * 请求处理前执行：核心验证逻辑
     * @return true=验证通过（放行），false=验证失败（拦截）
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 从请求头获取Authorization令牌（前端格式：Bearer {token}）
        String authHeader = request.getHeader("Authorization");

        // 2. 验证令牌是否存在+格式正确
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            return set401Response(response, "未携带有效令牌，请先登录");
        }

        // 3. 提取纯令牌（去掉"Bearer "前缀，注意空格）
        String token = authHeader.replace("Bearer ", "");

        try {
            // 4. 解析令牌，提取用户信息（loginId和role）
            String currentLoginId = jwtUtil.extractLoginId(token);
            String currentRole = jwtUtil.extractRole(token); // 后续优化JwtUtil后可用

            // 5. 验证令牌是否过期
            if (jwtUtil.isTokenExpired(token)) {
                return set401Response(response, "令牌已过期，请重新登录");
            }

            // 6. （关键）将用户信息存入请求属性，供Controller直接使用（无需重复解析）
            request.setAttribute("currentLoginId", currentLoginId);
            request.setAttribute("currentRole", currentRole);
            LoginUser.setCurrentId(currentLoginId);

            // 7. 角色权限控制（根据接口路径判断角色）
            String requestPath = request.getRequestURI();
            // 管理员接口必须是admin角色
            if (requestPath.startsWith("/admins/") && !"admin".equals(currentRole)) {
                return set401Response(response, "无管理员权限，拒绝访问");
            }
            // 教师接口必须是teacher角色（后续扩展）
            if (requestPath.startsWith("/teachers/") && !"teacher".equals(currentRole)) {
                return set401Response(response, "无教师权限，拒绝访问");
            }

            // 8. 所有验证通过，放行请求
            return true;

        } catch (ExpiredJwtException e) {
            // 令牌过期异常
            return set401Response(response, "令牌已过期，请重新登录");
        } catch (SignatureException e) {
            // 令牌签名错误（可能被篡改）
            return set401Response(response, "令牌无效，可能被篡改");
        } catch (Exception e) {
            // 其他异常（如令牌格式错误、密钥不匹配）
            return set401Response(response, "令牌验证失败，请重新登录");
        }
    }

    /**
     * 封装401响应：统一返回Result格式的JSON
     */
    private boolean set401Response(HttpServletResponse response, String msg) throws Exception {
        // 设置响应类型为JSON，避免前端解析错误
        response.setContentType("application/json;charset=UTF-8");
        // 设置响应状态码401（Unauthorized）
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

        // 构建与项目一致的Result错误格式
        ResultUtil errorResult =  ResultUtil.error(msg);
        // 写入响应体
        ObjectMapper objectMapper = new ObjectMapper();
        response.getWriter().write(objectMapper.writeValueAsString(errorResult));

        // 返回false，终止请求（不进入Controller）
        return false;
    }
}